package com.vm.dao;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Query;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.vm.common.MapPage;
import com.vm.common.Page;
import com.vm.common.QueryObject;
import com.vm.entity.Agency;
import com.vm.entity.Role;
import com.vm.entity.User;


public class BaseDAOImpl<T, PK extends Serializable> extends HibernateDaoSupport implements BaseDAO<T, PK> {

	private Class<T> entityClass;

	public void setEntityClass(Class<T> classzz) {
		this.entityClass = classzz;
	}

	public void delete(T entity) {
		super.getHibernateTemplate().delete(entity);
	}

	public void deleteById(Class entityClass, PK id) {
		super.getHibernateTemplate().delete(findById(entityClass, id));

	}

	public void deleteByHql(String hql , Object[] params) {
		Query query = super.getSession().createQuery(hql);
		this.setQueryParams(query, params);
		query.executeUpdate();

	}
	
	public Serializable save(T entity) {
		return super.getHibernateTemplate().save(entity);

	}

	public void saveOrUpdate(T entity) {
		super.getHibernateTemplate().saveOrUpdate(entity);

	}

	public void update(T entity) {
		super.getHibernateTemplate().update(entity);
	}

	public void update(String hql, Object[] params) {
		Query query = super.getSession().createQuery(hql);
		this.setQueryParams(query, params);
		query.executeUpdate();
	}

	public List<T> findAll(Class entityClass) {
		return super.getHibernateTemplate().loadAll(entityClass);
	}

	public List<T> findAll(Class entityClass, String hql, Object[] params, int start, int limit) {
		Query query = super.getSession().createQuery(hql);
		this.setQueryParams(query, params);
		if (limit != 0) {
			query.setFirstResult(start).setMaxResults(limit);
		}
		return query.list();
	}

	public List<T> findAll(Class entityClass, String hql, Object[] params, int limit) {
		Query query = super.getSession().createQuery(hql);
		this.setQueryParams(query, params);
		if (limit != 0) {
			query.setMaxResults(limit);
		}
		return query.list();
	}

	public List<T> findAll(Class<T> entityClass, int start, int limit) {
		Query query = super.getSession().createQuery("from " + entityClass.getName());
		query.setFirstResult(start).setMaxResults(limit);
		return query.list();
	}

	public List<T> findAll(Class<T> entityClass, String hql, int limit) {
		Query query = super.getSession().createQuery(hql);
		if (limit != 0) {
			query.setMaxResults(limit);
		}
		return query.list();
	}
	 
	public List<T> findByHql(String hql, Object[] params) {
		Query query = super.getSession().createQuery(hql);
		this.setQueryParams(query, params);
		return query.list();
	}

	public T findById(Class entityClass, PK id) {
		if (id == null) return null;
		return (T) super.getHibernateTemplate().get(entityClass, id);
	}
	/**
	 * hql查询
	 * 查询指定属性
	 * @param hql
	 * @return
	 */
	public List findAll(String hql){
		Query query = super.getSession().createQuery(hql);
		List list = new ArrayList();
		list=query.list();
		return list;
	}

	public List<T> findByProperty(Class entityClass, String propertyName, Object value) {
		String queryString = "from " + entityClass.getName() + " as temp where temp." + propertyName + "=?";
		return super.getHibernateTemplate().find(queryString, value);
	}

	public int getTotalCount(Class entityClass) {
		Long rowCount = (Long) super.getSession().createQuery("select count(*) from " + entityClass.getName()).uniqueResult();
		return rowCount.intValue();
	}

	public int getTotalCount(String countHql ,Object[] params){
		
		Query query = super.getSession().createQuery(countHql);
		this.setQueryParams(query, params);
		Long result = (Long) query.uniqueResult();
		
		return result.intValue();
	}
	
	public Page<T> pageForOrderByIdDesc(int pageSize, int currentPage) {
		int rowCount = getTotalCount();
		Page<T> page = new Page<T>(rowCount, currentPage, pageSize);

		currentPage = page.getCurrent();

		if (rowCount == 0) return page;
		int start = (currentPage - 1) * pageSize;

		Query query = super.getSession().createQuery("from " + entityClass.getName() + " order by id desc");
		query.setFirstResult(start).setMaxResults(pageSize);
		List<T> list = query.list();
		page.setList(list);

		return page;
	}

	public Page<T> page(int pageSize, int currentPage) {
		int rowCount = getTotalCount();
		Page<T> page = new Page<T>(rowCount, currentPage, pageSize);

		currentPage = page.getCurrent();

		if (rowCount == 0) return page;
		int start = (currentPage - 1) * pageSize;
		List<T> list = findAll(start, pageSize);
		page.setList(list);

		return page;
	}

	public Page<T> page(String hql, int pageSize, int currentPage) {
		Query query = super.getSession().createQuery("select count(*) from " + entityClass.getName());
		Long result = (Long) query.uniqueResult();
		int rowCount = result.intValue();

		return this.page(hql, null, rowCount, pageSize, currentPage);

	}

	public Page<T> page(String hql, String countHql, Object[] params, int pageSize, int currentPage) {
		Query query = super.getSession().createQuery(countHql);
		this.setQueryParams(query, params);
		Long result = (Long) query.uniqueResult();
		int rowCount = result.intValue();

		return this.page(hql, params, rowCount, pageSize, currentPage);

	}

	public Page<T> page(String hql, Object[] params, int rowCount, int pageSize, int currentPage) {

		Page<T> page = new Page<T>(rowCount, currentPage, pageSize);

		currentPage = page.getCurrent();

		if (rowCount == 0) return page;
		int start = (currentPage - 1) * pageSize;
		List<T> list = this.findAll(entityClass, hql, params, start, pageSize);
		page.setList(list);

		return page;
	}

	/**
	 * 得到一个单独字段的值
	 * 
	 * @param hql
	 * @param params
	 * @return
	 */
	protected Object findBySingleValue(String hql, Object[] params) {

		Query query = super.getSession().createQuery(hql);
		setQueryParams(query, params);

		Object value = query.uniqueResult();

		return value;
	}

	/**
	 * 得到一个单独的对像,结果!=1时返回null
	 * 
	 * @param hql
	 * @param params
	 * @return
	 */
	protected T findBySingleObject(String hql, Object[] params) {

		List<T> list = this.findByHql(hql, params);

		if (list != null && list.size() == 1) {
			return list.get(0);
		}

		return null;
	}

	protected boolean validator(String hql ,Object[] params){
		Query query = super.getSession().createQuery(hql);
		this.setQueryParams(query, params);
		List list = query.list();
		if(list!=null&&list.size()>0){
			return true;
		}
		return false ;
	}
	
	@SuppressWarnings("unchecked")
	public  List<Map<String, Object>> findBySqlALL(String sql,Object[] params){
		Query query = super.getSession().createQuery(sql);
		this.setQueryParams(query, params);
		 List<Map<String, Object>> result = query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
		return result;
	}
	@SuppressWarnings("unchecked")
	public  List<Map<String, Object>> findBySqlALL(String sql,Object[] params,int limit){
		Query query = super.getSession().createQuery(sql);
		this.setQueryParams(query, params);
		 List<Map<String, Object>> result = query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).setMaxResults(limit).list();
		return result;
	}
	
	public Map<String,String> getSelectMap(String modelId){
		String sql = "select codeCd as cdoeCd,codeName as codeName from  Code where classCd=? order by sortNum";
		Query query = super.getSession().createQuery(sql);
		List list = query.setParameter(0, modelId).list(); 
		Map<String,String> map = new LinkedHashMap<String,String>();
		map.put(null, "-请选择-");
		for(Object sm : list){
			Object[] bjt = (Object[])sm;
			map.put(bjt[0]+"", bjt[1]+"");
		}
		return map;
	}
	
	public Map<String,String> getSelectPoMap(String hql){
		Query query = super.getSession().createQuery(hql);
		List list = query.list(); 
		Map<String,String> map = new LinkedHashMap<String,String>();
		map.put(null, "--请选择--");
		for(Object sm : list){
			Object[] bjt = (Object[])sm;
			if(bjt[1]!= null && !"".equals(bjt[1])){
				map.put(bjt[0]+"", bjt[1]+"");
			}
		}
		return map;
	}
	
	
	public Map<String,String> getSelectPoMap2(String sql){
		Query query = super.getSession().createQuery(sql);
		List list = query.list(); 
		Map<String,String> map = new LinkedHashMap<String,String>();
		map.put(null, "--请选择--");
		for(int i= 0;i<list.size();i++){
			String bjt = (String)list.get(0);
			if(bjt!= null && !"".equals(bjt)){
				map.put(bjt+"", bjt+"");
			}
		}
		return map;

	}

	public Map<String,String> getCheckBoxMap(String hql){
		Query query = super.getSession().createQuery(hql);
		List list = query.list(); 
		Map<String,String> map = new LinkedHashMap<String,String>();
		for(Object sm : list){
			Object[] bjt = (Object[])sm;
			map.put(bjt[0]+"", bjt[1]+"");
		}
		return map;
	}

	/***
	 * MapPage
	 * **/
	public MapPage findBySqlMapPage(String sql,String countSql,Object[] params,int pageSize, int currentPage){
		Query query = super.getSession().createQuery(countSql);
		this.setQueryParams(query, params);
		Long result = (Long) query.uniqueResult();
		int rowCount = result.intValue();
		MapPage resultMap = new MapPage(rowCount, currentPage, pageSize);
		if (rowCount == 0){
			return resultMap;
		}else{
			int start = (currentPage - 1) * pageSize;
			List<Map<String, Object>> list = findBySqlMapPage(sql,params,start,pageSize);
			resultMap.setList(list);
		} 
		return resultMap;
	}
	@SuppressWarnings("unchecked")
	public List<Map<String, Object>> findBySqlMapPage(String sql,Object[] params,int start, int limit){
		Query query = super.getSession().createQuery(sql);
		this.setQueryParams(query, params);
		 List<Map<String, Object>> result =  query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).setFirstResult(start).setMaxResults(limit).list();
		
		 return result;
	}
	/**
	 * 设定查询参数
	 * 
	 * @param query
	 * @param params
	 */
	protected void setQueryParams(Query query, Object[] params) {
		if (null != params && params.length > 0) {
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i, params[i]);
			}
		}
	}


	public void deleteById(PK id) {
		this.deleteById(this.entityClass, id);
	}

	public List<T> findAll() {
		return this.findAll(this.entityClass);
	}

	public List<T> findAll(String hql, Object[] params, int start, int limit) {
		return this.findAll(this.entityClass, hql, params, start, limit);
	}

	public List<T> findAll(int start, int limit) {
		return this.findAll(this.entityClass, start, limit);
	}

	public List<T> findAll(String hql, Object[] params, int limit) {
		return this.findAll(this.entityClass, hql, params, limit);
	}

	public List<T> findAll(String hql, int limit) {
		return this.findAll(this.entityClass, hql, limit);
	}

	public T findById(PK id) {
		return this.findById(this.entityClass, id);
	}

	public List<T> findByProperty(String propertyName, Object value) {
		return this.findByProperty(this.entityClass, propertyName, value);
	}

	public int getTotalCount() {
		return this.getTotalCount(this.entityClass);
	}
	public String getGrp(String className,String grpAttribute){
		String hql = "SELECT MAX("+grpAttribute+") FROM "+className;
		List list =  this.findByHql(hql, null);
		String value = "";
		for(Object object : list){
			if(object != null){
				value = object.toString()+"0";
			}else{
				value = "1";
			}
		}
		return value;
	}
	
	public String getAllGrp(String rlGrp){
		String [] roleids = this.getGrpValues(rlGrp);
		if(roleids == null || roleids.length<1){
			return "";
		}
		Query query = getSession().getNamedQuery("ModulPrmssCd");
        query.setParameterList("modulCd", roleids);
        List<Role> list = (List<Role>) query.list();
        if(list == null){
        	return "";
        }
        List<String> menuGrpList = new ArrayList<String>();
        for(Role role :list){
        	menuGrpList.add(role.getPrmssGrp());
        }
		return this.sumGrp(menuGrpList);
	}
	
	public List<String> getUserRoleID(String rlGrp,User user){
		String [] roleids = this.getGrpValues(rlGrp);
		List<String> list = new ArrayList<String>();
		if(roleids == null || roleids.length<1){
			return list;
		}
		Query query = getSession().getNamedQuery("ModulPrmssCd");
        query.setParameterList("modulCd", roleids);
        List<Role> rolelist = (List<Role>) query.list();
        if(list == null){
        	return list;
        }
        boolean flg = false;
        for(Role role :rolelist){
        	list.add(role.getRlId());
        	if("0".equals(role.getSignAddCd())){
        		flg = true;
        	}
        }
        if(flg){
        	user.setLoginWelecom("0");
        }else{
        	user.setLoginWelecom("1");
        }
		return list;
	}
	
	/**
	 * 得到单个对象
	 */
	public Object findObject(Class entityClass, PK id) {
		if (id == null) return null;
		return super.getHibernateTemplate().get(entityClass, id);
	}

	/**
	 * 将多种权限组合成一种
	 * @param menuGrpList
	 * @return
	 */
	public String sumGrp(List<String> menuGrpList){
		String[] values = null;
		for(String val : menuGrpList){
			String[] vtl = val.split("");
			if(values == null){
				values = vtl;
				continue;
			}
			if(vtl.length > values.length){
				for(int i=1;i<values.length; i++){
					if("1".equals(values[values.length-i]) || "1".equals(vtl[vtl.length-i])){
						vtl[vtl.length-i] = "1";
					}else{
						vtl[vtl.length-i] = "0";
					}
				}
				values = vtl;
			}else{
				for(int i=1;i<vtl.length; i++){
					if("1".equals(values[values.length-i]) || "1".equals(vtl[vtl.length-i])){
						values[values.length-i] = "1";
					}else{
						values[values.length-i] = "0";
					}
					
				}
			}
		}
		if(values == null){
			return "";
		}
		StringBuffer sbf = new StringBuffer();
		for(int i=0;i<values.length;i++){
			if("".equals(values[i])){
				continue;
			}
			sbf.append(values[i]);
		}
		return sbf.toString();
	}
	
	public String[] getGrpValues(String grp){
		List<String> listValue = new ArrayList<String>();
		if(grp == null || "".equals(grp)){
			return new String[0];
		}
		
		char[] vt = grp.toCharArray();
		for(int i=0;i<vt.length;i++){
			if("1".equals(vt[i]+"")){
				StringBuffer sval = new StringBuffer("1");
				for(int j=vt.length-i;j>1;j--){
					sval.append("0");
				}
				listValue.add(sval.toString());
			}
		}
		String[] values = new String[listValue.size()];
		return listValue.toArray(values);
	}
	
	public  String getButtonValues(String[] grpValues){
		if(grpValues == null || grpValues.length<1){
			return "";
		}
		int[] grpLength = new int[grpValues.length];
		int maxlength =0;
		for(int i=0;i<grpValues.length;i++){
			int index  = grpValues[i].length();
			grpLength[i] = index;
			if(index > maxlength){
				maxlength = index;
			}
		}
		StringBuffer sbf = new StringBuffer();
		for(int i=0;i<maxlength;i++){
			sbf.append("0");
		}
		char[] value = sbf.toString().toCharArray();
		for(int i=0;i<grpLength.length;i++){
			value[grpLength[i]-1] = 1+'0';
		}
		sbf = new StringBuffer();
		for(int i=value.length-1;i>=0;i--){
			sbf.append(value[(int)i]);
		}
		return sbf.toString();
	}

	
	public String getAdditionalSQL(Class actionClass) {
		try {
			Object obj = actionClass.newInstance();
			Method method = actionClass.getDeclaredMethod("AdditionalSQL"); 
			//Method method=actionClass.getMethod("AdditionalSQL", BaseDAOImpl.class);//第一个参数为方法名称，后面参数为可变参数
			//return (String) method.invoke(obj,BaseDAOImpl.class.newInstance()); //第一个参数表示类的实例化对象，第二个及其以后参数为可变参数
			return (String) method.invoke(obj);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			 return "";
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return "";
	}

	
	public Map<String,Boolean> seletButtonGrp(User user,String actionName){
		Map<String,Boolean> grpMap = new HashMap<String, Boolean>();
		grpMap.put("resetPassword", false);
		String hql = "select ename,prmssVal from GrpButton";
		List<Object[]> list = this.findAll(hql);
		if(user.isSuperAdmin()){
			for(Object[] object:list){
				grpMap.put(object[0]+"", true);
			}
			grpMap.put("resetPassword", true);
			return grpMap;
		}
		if(user.getGrpUrlMap() != null && user.getRoleId() != null && user.getRoleId().size()>0){
			StringBuffer roleId = new StringBuffer();
			for(String rid : user.getRoleId()){
				roleId.append("'");
				roleId.append(rid);
				roleId.append("',");
			}
			String mbHql = "select prmssVal from MenuButton where menuId='"+user.getGrpUrlMap().get(actionName)+"' and rlId in("+roleId.substring(0, roleId.length()-1)+")";
			List btlist = this.findAll(mbHql);
			List<String> grpList = new ArrayList<String>();
			for(Object obj : btlist){
				grpList.add(obj+"");
			}
			String[] btGrp = this.getGrpValues(this.sumGrp(grpList));
			for(Object[] object:list){
				for(String st : btGrp){
					if((object[1]+"").equals(st)){
						grpMap.put(object[0]+"", true);
						continue;
					}
				}
				if(grpMap.get(object[0]+"") == null){
					grpMap.put(object[0]+"",false);
				}
			}
		}
		return grpMap;
	}
//	public String getBrowsAreaNo(User user){
//		return this.getAreaNo(this.getGrpValues(user.getBrwsOrgNo()));
//	}
	
	public String getAreaNo(User user){
		String value = "";
		if(user == null){
			return value;
		}
		
		String[] arGrp= this.getGrpValues(user.getBrwsOrgNo());
		StringBuffer areaNo = new StringBuffer();
		if(arGrp != null && arGrp.length>0){
			Query query = getSession().getNamedQuery("AgencyAll");
			query.setParameterList("arGrp", arGrp);
			List<Agency> list = query.list();
			for(Agency agency : list){
				if(agency.getOrgNo() != null && !"".equals(agency.getOrgNo())){
					areaNo.append("'"+agency.getOrgNo()+"',");
				}
			}
		}
		if(user.getBlngOrgNo() != null && !"".equals(user.getBlngOrgNo())){
			areaNo.append("'"+user.getBlngOrgNo()+"',");
			value = "'"+user.getBlngOrgNo()+"'";
		}
		
		if(areaNo != null && areaNo.length()>0){
			value = areaNo.substring(0,areaNo.length()-1);
		}
		return value;
	}
}
